<script>
  // import { App, nextTick } from 'vue'
  // 根据el获取input

  import common from '@/utils/common'

  /**
   *  const getInput = (el: HTMLElement): HTMLInputElement
   * | null => (el instanceof HTMLInputElement ? el : el.querySelector('input'))
   */
  export default {
    install(app) {
      // v-focus 自动聚焦。对于非文本框聚焦使用 v-focus:1
      // app.directive('focus', {
      //     mounted: async (el: HTMLElement, { arg }) => {
      //         // 为了防止数据未即使更新。
      //         await nextTick()
      //         // 对于非文本框聚焦（使用了 contenteditable ）的直接聚焦即可
      //         if (arg) el.focus?.()
      //         else getInput(el)?.focus()
      //     }
      // })

      // // v-select 自动选中。对于非文本框请使用 v-select:1
      // app.directive('select', {
      //     mounted: async (el: HTMLElement, { arg }) => {
      //         // 为了防止数据未即使更新。
      //         await nextTick()
      //         if (arg) el
      //         // elementplus的文本框。是嵌套了一个文本框。。
      //         getInput(el)?.select()
      //     }
      // })

      let inputHandler = () => {}
      // 限制input框，仅能输入数字。默认限制输入整数，可以通过传参设置小数位数
      // v-number 限制整数，v-number:2 限制两位小数，
      // v-number:2=3 限制两位小数，整数位三位，v-number=2 限制两位整数\
      app.directive('number', {
        mounted(el, { arg, value }, vnode) {
          const input = el.querySelector('input')
          if (el) {
            // 小数正则
            const decimal = arg ? `(\\.\\d{0,${arg}})?` : ''
            // 整数正则
            const integer = value ? `(0|[1-9]\\d{0, ${value - 1}})` : '\\d*'
            const regExp = new RegExp(integer + decimal, 'g')
            inputHandler = () => {
              //解决中文输入双向绑定失效
              if (vnode.locking) {
                return
              }
              // 替换所有的非数字项
              // 如果输入的数字不符合正则表达式，则替换为''
              input.value =
                input.value
                  .toString()
                  .trim()
                  .replace(/[^\d.]/g, '')
                  ?.match?.(regExp)?.[0] ?? ''
            }
            input.addEventListener('input', inputHandler, true)

            input.addEventListener('compositionstart', () => {
              vnode.locking = true //解决中文输入双向绑定失效
            })
            input.addEventListener('compositionend', () => {
              vnode.locking = false //解决中文输入双向绑定失效
              input.dispatchEvent(new Event('input'))
            })
          }
        },
        unmounted(el) {
          const input = el.querySelector('input')
          input.removeEventListener('input', inputHandler, true)
          input.removeEventListener('compositionstart', inputHandler, true)
          input.removeEventListener('compositionend', inputHandler, true)
        },
      })
      app.directive('number2', {
        mounted(el, { arg = 2, value }, vnode) {
          const input = el.querySelector('input')
          if (el) {
            // 小数正则
            const decimal = arg ? `(\\.\\d{0,${arg}})?` : ''
            // 整数正则
            const integer = value ? `(0|[1-9]\\d{0, ${value - 1}})` : '\\d*'
            const regExp = new RegExp(integer + decimal, 'g')
            inputHandler = () => {
              //解决中文输入双向绑定失效
              if (vnode.locking) {
                return
              }
              // 替换所有的非数字项
              // 如果输入的数字不符合正则表达式，则替换为''
              input.value =
                input.value
                  .toString()
                  .trim()
                  .replace(/[^\d.]/g, '')
                  ?.match?.(regExp)?.[0] ?? ''
            }
            input.addEventListener('input', inputHandler, true)
            input.addEventListener('compositionstart', () => {
              vnode.locking = true //解决中文输入双向绑定失效
            })
            input.addEventListener('compositionend', () => {
              vnode.locking = false //解决中文输入双向绑定失效
              input.dispatchEvent(new Event('input'))
            })
          }
        },
        unmounted(el) {
          const input = el.querySelector('input')
          input.removeEventListener('input', inputHandler, true)
          input.removeEventListener('compositionstart', inputHandler, true)
          input.removeEventListener('compositionend', inputHandler, true)
        },
      })
      app.directive('numberChange', {
        mounted(el, { arg = 2, value }) {
          const input = el.querySelector('input')
          if (el) {
            // 小数正则
            const decimal = arg ? `(\\.\\d{0,${arg}})?` : ''
            // 整数正则
            const integer = value ? `(0|[1-9]\\d{0, ${value - 1}})` : '\\d*'
            const regExp = new RegExp(integer + decimal, 'g')
            inputHandler = () => {
              const tmpStr = input.value.toString().trim()

              const str =
                tmpStr.replace(/[^\d.]/g, '')?.match?.(regExp)?.[0] ?? ''
              if (str) {
                // 替换所有的非数字项
                // 如果输入的数字不符合正则表达式，则替换为''
                input.value = str
                if (tmpStr !== str) {
                  let msg = ''
                  if (value && arg)
                    msg += `仅支持${value}位整数，和${arg}位小数`
                  if (!value && arg) msg += `仅支持${arg}位小数`
                  common.XmMessage(1, msg)
                }
              } else {
                input.value = ''
                common.XmMessage(1, '仅支持输入数字')
              }
            }
            input.addEventListener('change', inputHandler, true)
          }
        },
        unmounted(el) {
          const input = el.querySelector('input')
          input.removeEventListener('input', inputHandler, true)
        },
      })
    },
  }
</script>
